/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.buzzwords.model;

import com.buzzwords.clientside.model.ClientDefinition;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Text;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;

/**
 * Defintion represents specific definition of a buzzword. Belongs to a locale
 * and can differ between different locales. Definition has many ratings
 *
 * @author potlow
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
public class Definition {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    // a definition of buzzword
    @Persistent
    private Text definition;

    // category of buzzword
    @Persistent
    @Enumerated(EnumType.STRING)
    private ClientDefinition.DefinitionCategoryTypes category;

    // part of speech buzzword is
    @Persistent
    @Enumerated(EnumType.STRING)
    private ClientDefinition.DefinitionSpeechTypes partOfSpeech;

    // an example of usage in a sentence
    @Persistent
    private String usageSentence = "";
    
    // exact location where buzzword was created
    @Persistent
    private Double creationLatitude;

    @Persistent
    private Double creationLongitude;

    // user name of creating user
    @Persistent
    private String username;

    // list of ratings for definition
    @Persistent(mappedBy="definition")
    private List<Rating> ratings = new ArrayList<Rating>();

    // number of likes for this definiton (for convience)
    @Persistent
    private int likes;

    // creation date
    @Persistent
    private Date creationDate;

    @Persistent
    private Locale locale;

    /**
     * Constructor
     * @param definition definition of buzzword
     * @param category category of buzzword
     * @param partOfSpeech part of speech of buzzword
     * @param usageSentence buzzword used in a sentence
     * @param latitude latitude buzzword was created for
     * @param longitude longitude buzzword was created for
     */
    public Definition(String definition, ClientDefinition.DefinitionCategoryTypes category,
            ClientDefinition.DefinitionSpeechTypes partOfSpeech, String usageSentence,
            float latitude, float longitude, User user) {
        this.definition = new Text(definition);
        this.category = category;
        this.partOfSpeech = partOfSpeech;
        this.usageSentence = usageSentence;
        this.creationLatitude = (double)latitude;
        this.creationLongitude = (double)longitude;
        this.username = user.getUsername();

        this.likes = 0;
        this.creationDate = new Date();
    }

    /**
     * Default constructor
     */
    public Definition() {
    }

    public ClientDefinition.DefinitionCategoryTypes getCategory() {
        return category;
    }

    public void setCategory(ClientDefinition.DefinitionCategoryTypes category) {
        this.category = category;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public Double getCreationLatitude() {
        return creationLatitude;
    }

    public void setCreationLatitude(Double creationLatitude) {
        this.creationLatitude = creationLatitude;
    }

    public Double getCreationLongitude() {
        return creationLongitude;
    }

    public void setCreationLongitude(Double creationLongitude) {
        this.creationLongitude = creationLongitude;
    }

    public Text getDefinition() {
        return definition;
    }

    public void setDefinition(Text definition) {
        this.definition = definition;
    }

    public Key getKey() {
        return key;
    }

    public void setKey(Key key) {
        this.key = key;
    }

    public ClientDefinition.DefinitionSpeechTypes getPartOfSpeech() {
        return partOfSpeech;
    }

    public void setPartOfSpeech(ClientDefinition.DefinitionSpeechTypes partOfSpeech) {
        this.partOfSpeech = partOfSpeech;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public List<Rating> getRatings() {
        return ratings;
    }

    public void setRatings(List<Rating> ratings) {
        this.ratings = ratings;
    }

    public String getUsageSentence() {
        return usageSentence;
    }

    public void setUsageSentence(String usageSentence) {
        this.usageSentence = usageSentence;
    }

    public int getLikes() {
        return likes;
    }

    public void setLikes(int likes) {
        this.likes = likes;
    }

    public Locale getLocale() {
        return locale;
    }

    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    public ClientDefinition getClientDefinition() {
        ClientDefinition clientDefinition = new ClientDefinition();
        clientDefinition.setKey(KeyFactory.keyToString(key));
        clientDefinition.setDefinition(definition.toString());
        clientDefinition.setCategory(category);
        clientDefinition.setPartOfSpeech(partOfSpeech);
        clientDefinition.setUsageSentence(usageSentence);
        clientDefinition.setUsername(username);
        clientDefinition.setLikes(likes);
        clientDefinition.setCreationLatitude(creationLatitude);
        clientDefinition.setCreationLongitude(creationLongitude);
        
        for(Rating rating : ratings)
            clientDefinition.getRatings().add(rating.getClientRating());

        return clientDefinition;
    }
}
